<template>
    <div>
        <!--面包屑导航区-->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        
        <!--卡片视图区-->
        <el-card>
            <!--搜索与添加区域-->
            <!--el-row是在layout布局里,:gutter表示不同el-col的间距,el-span表示每个占多宽的距离-->
            <el-row>
                <el-col>
                    <el-button type="primary" @click="addRoleDialogVisible = true">添加角色</el-button>
                </el-col>
            </el-row>
            <!--角色列表区域-->
            <el-table :data="rolelist" border stripe>
                
                <!--展开列,加上expand即可-->
                <el-table-column type="expand">
                  <template slot-scope="scope">
                      <!--:class="['bdbottom'添加上下边框线-->
                      <!--closable @close=""这时配套的，标签上有小叉号，并添加点击事件-->
                      <!--一级二级和三级权限删除操作相同-->
                      <el-row v-for="(item1,i1) in scope.row.children" :key="item1.id"
                       :class="['bdbottom',i1 === 0 ?'bdtop':'','vcenter']">
                          <!--渲染一级权限-->
                          <!--:span="5"设置宽度-->
                          <!--el-col和el-span都是layout布局里的-->
                          <el-col :span="5">
                             <el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
                              <!--右箭头图标-->
                              <i class="el-icon-caret-right"></i>
                          </el-col>
                          <!--渲染二级和三级权限-->
                          <el-col :span="19">
                              <!--通过for循环，嵌套渲染二级权限-->
                              <el-row v-for="(item2,i2) in item1.children" :key="item2.id"
                              :class="[i2 ===0 ? '' : 'bdtop','vcenter']">
                                <el-col :span="6">
                                    <el-tag type="success" closable @close="removeRightById(scope.row,item2.id)">{{item2.authName}}</el-tag>
                                    <!--右箭头图标-->
                                    <i class="el-icon-caret-right"></i>
                                </el-col>
                                  <el-col :span="18">
                                      <!--closable @close=""这时配套的，标签上有小叉号，并添加点击事件-->
                                      <el-tag v-for="item3 in item2.children" :key="item3.id"
                                              type="warning" closable @close="removeRightById(scope.row,item3.id)"
                                      >{{item3.authName}}</el-tag>
                                  </el-col>
                              </el-row>
                          </el-col>
                      </el-row>
                  </template>
                </el-table-column>
                <!--这个索引列是element-ui自带的-->
                <el-table-column type="index"></el-table-column>
                <el-table-column label="角色名称" prop="roleName"></el-table-column>
                <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
                <!--放不下三个按钮，手动给宽度，这样就能一行显示了-->
                <el-table-column label="操作" width="300px">
                    <template  slot-scope="scope">
                        <!--手动设置大小：size="mini"-->
                        <!--修改按钮，添加事件,要获取到id等值，用作用域插槽-->
                        <el-button type="primary" icon="el-icon-edit" size="mini" @click="editRole(scope.row.id)">编辑</el-button>
                        <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeRoleById(scope.row.id)">删除</el-button>
                        <el-button type="warning" icon="el-icon-setting" size="mini"
                        @click="showSetRightDialog(scope.row)">分配权限</el-button>
                    </template>
                </el-table-column>
            </el-table>
            
            <!--分配权限对话框-->
            <!--监听分配权限对话框的关闭事件-->
            <el-dialog
                    title="修改用户"
                    :visible.sync="setRightDialogVisible"
                    width="50%" @close="setRightDialogClosed">
                <!--树型控件-->
                <!--:props重要，是指要绑定的对应字段名称，在data中配置-->
                <!--show-checkbox显示复选框,node-key="id"复选框选中，就是传入id值-->
                <!--default-expand-all：默认展开-->
                <!--:default-checked-keys="defKeys"，默认选中的值，获取该行所有三级权限id，保存到defKeys数组中即可-->
                <!--ref="treeRef"添加引用，方便获取到内容-->
                <el-tree :data="rightsList" :props="treeProps" show-checkbox
                node-key="id" default-expand-all
                :default-checked-keys="defKeys" ref="treeRef"></el-tree>
              <span slot="footer" class="dialog-footer">
                <el-button @click="setRightDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="allotRights">确 定</el-button>
              </span>
            </el-dialog>
    
            <!--添加角色对话框-->
            <!--width="50%"对话框占屏幕宽度一半-->
            <!--addDialogVisible控制对话框是否关闭-->
            <!--@close在关闭对话框时清空表单-->
            <el-dialog
                    title="添加角色"
                    :visible.sync="addRoleDialogVisible"
                    width="50%"
                    @close="addRoleDialogClosed">
                <!--内容主体区域-->
                <!--添加表单-->
                <el-form :model="addForm"  ref="ruleFormRef" label-width="70px">
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input v-model="addForm.roleName"></el-input>
                    </el-form-item>
                    <el-form-item label="角色描述" prop="roleDesc">
                        <el-input v-model="addForm.roleDesc"></el-input>
                    </el-form-item>
                </el-form>
                <!--底部区域-->
                <span slot="footer" class="dialog-footer">
                <el-button @click="addRoleDialogVisible = false">取 消</el-button>
                <el-button type="primary"  @click="addUser">确 定</el-button>
            </span>
            </el-dialog>
    
            <!--修改角色对话框-->
            <el-dialog
                    title="修改角色"
                    :visible.sync="editRoleDialogVisible"
                    width="50%"
                    @close="editRoleDialogClosed">
                <!--内容主体区域-->
                <!--修改表单,editForm绑定根据id获取到的数据-->
                <el-form :model="editRoleForm"  ref="editFormRef" label-width="70px">
                    <el-form-item label="角色名称">
                        <!--disabled表示不可修改-->
                        <el-input v-model="editRoleForm.roleName"></el-input>
                    </el-form-item>
                    <el-form-item label="角色描述">
                        <el-input v-model="editRoleForm.roleDesc"></el-input>
                    </el-form-item>
                </el-form>
                <!--底部区域-->
                <span slot="footer" class="dialog-footer">
                <el-button @click="editRoleDialogVisible = false">取 消</el-button>
                <el-button type="primary"  @click="editRoleInfo">确 定</el-button>
            </span>
            </el-dialog>
        </el-card>
        
    </div>
</template>

<script>
  export default {
    name: 'Roles',
    data() {
      return{
        rolelist:[],
        //控制分配权限对话框的显示与隐藏
        setRightDialogVisible:false,
        //所有权限的数据，获取权限时使用
        rightsList:[],
        //树形控件的属性绑定
        treeProps:{
          //label是指要显示的名称,children是指获取的子元素名称，要和获取到的数据一一对应
          label:'authName',
          children:'children'
        },
        defKeys:[],
        //当前即将分配权限的角色id
        roleId:'',
        //添加角色对话框
        addRoleDialogVisible:false,
        addForm:{
          roleName:'',
          roleDesc:''
        },
        editRoleDialogVisible:false,
        editRoleForm:{}
      }
    },
    created () {
      this.getRoleList()
    },
    methods:{
      getRoleList(){
        this.$http.get('roles')
        .then(res => {
          if (res.data.meta.status !== 200){
            return this.$message.error('获取用户列表失败')
          }
          this.rolelist = res.data.data
          // console.log(this.rolelist)
        })
      },
      //删除操作,第一个是角色数据，第二个是要删除的权限id
      removeRightById(row,rightId) {
        //这是弹框组件
        this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then((res) => {
          //确认时res会返回confirm
          if (res === 'confirm') {
            //发起请求删除用户信息
            this.$http.delete(`roles/${row.id}/rights/${rightId}`)
              .then(res => {
                if (res.data.meta.status !==200) {
                  return  this.$message.error('删除权限失败')
                }
                this.$message.success('删除权限成功')
                //重要：不建议使用this.getRoleList()
                //因为调用它会重新渲染页面，这样已打开的就被关闭了，还得再次打开
                // this.getRoleList()
                //这样进行重新赋值最好
                row.children = res.data.data
              })
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },
      showSetRightDialog(role) {
        //当前即将分权权限的角色id
        this.roleId = role.id
        
        this.$http.get('rights/tree')
        .then(res => {
          if (res.data.meta.status !==200) {
            return  this.$message.error('获取权限数据失败')
          }
          //把获取到的权限数据保存
          this.rightsList = res.data.data
          console.log(this.rightsList)
          
         //递归获取三级节点
          this.getLeafKeys(role,this.defKeys)
          //展示对话框
          this.setRightDialogVisible = true
        })
        
      },
      //通过递归方式，获取角色下所有三级权限的id,并保存到defKys数组中
      getLeafKeys(node,arr) {
        //如果节点没有包含children，则说明是三级节点
        if (!node.children) {
          return arr.push(node.id)
        }
      //  递归调用，获取到三级节点
      node.children.forEach(item =>{
        this.getLeafKeys(item,arr)
      })
      },
      //每次点击按钮时，都会把权限id保存到数组中，这样数组会越来越大，后面再打开
      //按钮显示就不对了，因此每次关闭对话框时要清空数组
      setRightDialogClosed() {
        this.defKeys = []
      },
      allotRights() {
        //点击为角色分配权限
        //getCheckedKeys这是tree组件自带的函数
        //将两个数组拼在一起，...展开运算符
        const keys = [
          ...this.$refs.treeRef.getCheckedKeys(),
          ...this.$refs.treeRef.getHalfCheckedKeys()
        ]
        console.log(keys)
        const idStr = keys.join(",")
        this.$http.post(`roles/${this.roleId}/rights`,{rids:idStr})
        .then(res =>{
          if (res.data.meta.status !==200) {
            return  this.$message.error('分配权限数据失败')
          }
          this.$message.success('分配权限成功')
          this.getRoleList()
          this.setRightDialogVisible = false
        })
      },
      addRoleDialogClosed() {
        this.$refs.ruleFormRef.resetFields()
      },
      addUser() {
        this.$http.post('roles',this.addForm)
          .then(res => {
            if (res.data.meta !== 201){
              this.$message.error('添加角色失败')
            }
            //必备三步
            this.$message.success('添加角色成功')
            //重新获取用户列表
            this.getRoleList()
            //关闭窗口
            this.addRoleDialogVisible= false

          })
      },
      //打开编辑框时，根据id查找到角色
      editRole(id) {
        this.$http.get('roles/'+id)
          .then(res => {
            if (res.data.meta.status !== 200){
              return this.$message.error('查询角色失败')
            }
            this.$message.success('查询角色成功')
            this.editRoleForm = res.data.data
            console.log(this.editRoleForm)
          })
        this.editRoleDialogVisible = true
      },
      //关闭更新对话框时返回原样
      editRoleDialogClosed() {
        this.$refs.editFormRef.resetFields()
      },
      //修改用户信息并提交
      editRoleInfo() {
        this.$http.put(`roles/`+this.editRoleForm.roleId,
          {roleName:this.editRoleForm.roleName,
                roleDesc:this.editRoleForm.roleDesc})
          .then(res => {
            console.log(res)
            if (res.data.meta.status !== 200){
              this.$message.error('更新角色失败')
            }
            //关闭窗口
            this.editRoleDialogVisible = false
            //重新获取用户列表
            this.getRoleList()
            //提示用户修改成功
            this.$message.success('更新角色成功')
          })
      },
      //删除角色
      removeRoleById (id) {
        //这是弹框组件
        this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then((res) => {
          //确认时res会返回confirm
          if (res === 'confirm') {
            //发起请求删除用户信息
            this.$http.delete('roles/'+id)
              .then(res => {
                if (res.data.meta.status !==200) {
                  return  this.$message.error('删除用户失败')
                }
                this.$message.success('删除用户成功')
                this.getRoleList()
              })
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      }
    }
  }
</script>

<style scoped>
    .bdtop {
        border-top:1px solid #eee ;
    }
    .bdbottom {
        border-bottom: 1px solid #eee;
    }
    /*纵向上居中对齐*/
    .vcenter {
        display: flex;
        align-items: center;
    }
</style>
